﻿using System;
using System.IO;
using System.Net.Mail;
using System.Reflection;

namespace Sendmail.Server
{
    /*
     * By Allan Eagle
     * http://www.codeproject.com/Articles/32434/Adding-Save-functionality-to-Microsoft-Net-Mail-Ma
     */
    public static class MailMessageExt
    {
        public static void Save(this MailMessage message, string fileName)
        {
            var assembly = typeof(SmtpClient).Assembly;
            var mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");
            using (var fileStream = new FileStream(fileName, FileMode.Create))
            {
                // Get reflection info for MailWriter contructor
                var mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(Stream) }, null);

                // Construct MailWriter object with our FileStream
                var mailWriter = mailWriterContructor.Invoke(new object[] { fileStream });

                // Get reflection info for Send() method on MailMessage
                var sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic);

                // Call method passing in MailWriter
                sendMethod.Invoke(message,BindingFlags.Instance | BindingFlags.NonPublic,null, new[] { mailWriter, true },null);

                // Finally get reflection info for Close() method on our MailWriter
                var closeMethod = mailWriter.GetType().GetMethod("Close",BindingFlags.Instance | BindingFlags.NonPublic);

                // Call close method
                closeMethod.Invoke(mailWriter, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { }, null);
            }
        }
    }
}
